#!/bin/python
# -*- coding: utf-8 -*-
"""
Name: global_var.py
Author: harrybao
Mail: harrybao@123u.com
Time: 2021/07/12 17:34
Desc: 第三方构建
"""
import os
import platform
from path_util import PathUtil

class ThirdPartyBuilder:
    """第三方构建类"""

    def __init__(self):
        pass
    
    def init_rpc_backend_cpp(self):
        """初始化rpc-backend-cpp"""

        rpc_backend_cpp_path = os.path.join(PathUtil().sdk_thirdparty_path, 'rpc-backend-cpp')
        
        if os.path.exists(rpc_backend_cpp_path):
            print('Rpc-backend-cpp existed.')
        else:
            print('Initializing rpc-backend-cpp...')

            if os.system("git clone https://gitee.com/dennis-kk/rpc-backend-cpp.git") != 0:
                print("git clone https://gitee.com/dennis-kk/rpc-backend-cpp.git failed")
                return False

        with open(os.path.join(rpc_backend_cpp_path, 'CMakeLists.txt'), 'w', encoding='utf-8') as f:
            f.write("cmake_minimum_required(VERSION 3.5)\n")
            if platform.system() == "Windows":
                f.write("set(CMAKE_CXX_STANDARD 17)\n")
            f.write("project (rpc-backend-cpp)\n")
            f.write(
                "SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../../lib/root)\n")
            f.write(
                'INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/src/coroutine)\n')
            if platform.system() == "Windows":
                f.write(
                    'set(SRC_LIST src/rpc.cpp src/rpc_proxy.cpp src/rpc_logger.cpp src/rpc_stub.cpp '
                    'src/rpc_statistics_impl.cpp src/coroutine/detail/timer.cpp src/coroutine/detail/coro_call.cpp '
                    'src/coroutine/windows/coroutine.cpp)\n')
            else:
                f.write(
                    'set(SRC_LIST src/rpc.cpp src/rpc_proxy.cpp src/rpc_logger.cpp src/rpc_stub.cpp '
                    'src/rpc_statistics_impl.cpp src/coroutine/detail/timer.cpp src/coroutine/detail/coro_call.cpp '
                    'src/coroutine/linux/coroutine.cpp)\n')
            f.write('add_library(rpc ${SRC_LIST})\n')
            f.write('SET_TARGET_PROPERTIES(rpc PROPERTIES PREFIX "lib")\n')
            f.write('SET_TARGET_PROPERTIES(rpc PROPERTIES SUFFIX ".a")\n')
            f.write(
                'target_compile_definitions(rpc PUBLIC\n$<$<CONFIG:Debug>: -DDEBUG -D_DEBUG>\n$<$<CONFIG:Release>: -DRELEASE>\n\n)\n')
            f.write("IF (MSVC)\n")
            f.write(
                'set_target_properties(rpc PROPERTIES COMPILE_FLAGS "/EHa /wd4267 /wd4311 /wd4302 /wd4312 /wd4244 '
                '/wd4065")\n')
            f.write('    foreach(var\n')
            f.write(
                '        CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE\n')
            f.write(
                '        CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO\n')
            f.write(
                '        CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE\n')
            f.write(
                '        CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO\n')
            f.write('    )\n')
            f.write('        if(${var} MATCHES "/MD")\n')
            f.write(
                '            string(REGEX REPLACE "/MD" "/MT" ${var} "${${var}}")\n')
            f.write('        endif()\n')
            f.write('    endforeach()\n')
            f.write("ELSE()\n")
            f.write('    if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")\n')
            f.write('        SET(CMAKE_CXX_FLAGS "' + ' -g -O2 -std=c++17 -Wall -fpermissive -fPIC")\n')
            f.write('        set(CMAKE_CXX_COMPILER "clang++")\n')
            f.write('    elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")\n')
            f.write('        SET(CMAKE_CXX_FLAGS "' + ' -g -O2 -std=c++17 -Wall -fpermissive -fPIC")\n')
            f.write('        set(CMAKE_CXX_COMPILER "g++")\n')
            f.write('    endif()\n')
            f.write("ENDIF ()\n")

        return self.build_rpc_backend_cpp()

    def build_rpc_backend_cpp(self):
        """编译rpc-backend-cpp"""

        rpc_backend_cpp_path = os.path.join(PathUtil().sdk_thirdparty_path, 'rpc-backend-cpp')
        os.chdir(rpc_backend_cpp_path)

        if platform.system() == "Windows":
            os.system('cmake -G  "Visual Studio 16 2019" -A x64')
            os.system('cmake --build . --config "Release"')
            os.system('cmake --build . --config "Debug"')
        else:
            os.system("cmake -DCMAKE_C_COMPILER=gcc  -DCMAKE_CXX_COMPILER=g++ .")
            os.system("make")
        return True

    def init_knet(self):
        """初始化knet"""
        
        knet_path = os.path.join(PathUtil().sdk_thirdparty_path, 'knet')

        if os.path.exists(knet_path):
            print('knet existed.')
        else:
            print('Initializing knet...')

            if os.system("git clone https://gitee.com/dennis-kk/knet.git") != 0:
                print("git clone https://gitee.com/dennis-kk/knet.git failed")
                return False
       
        return self.build_knet()

    def build_knet(self):
        """编译knet"""
        knet_path = os.path.join(PathUtil().sdk_thirdparty_path, 'knet')

        build_path = '{0}/build'.format(knet_path)
        if not os.path.exists(build_path):
            os.makedirs(build_path)

        if platform.system() == 'Windows':
            if os.system('cmake {0} -G "Visual Studio 16 2019" -A x64'.format(knet_path)) != 0:
                return False
            if os.system('cmake --build {0} --config "Release" --target knet'.format(knet_path)) != 0:
                return False
            # if os.system('cmake --build {0} --config "Debug" --target knet'.format(knet_path)) != 0:
            #     return False
        else:
            if os.system('cmake {0} -G "Unix Makefiles" -B{1}'.format(knet_path, build_path)) != 0:
                return False
            if os.system('cmake --build {0} --config "Release" --target knet'.format(build_path)) != 0:
                return False
            # if os.system('cmake --build {0} --config "Debug" --target knet'.format(build_path)) != 0:
            #     return False
            pass

        return True

